package com.imut.lagain.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imut.lagain.entity.User;
import com.imut.lagain.repository.UserRepository;
import com.imut.lagain.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户服务实现类
 */
@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserRepository, User> implements IUserService {
    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    
    /**
     * 根据openid查询用户
     * @param openid 微信openid
     * @return 用户信息
     */
    
        public User getUserByOpenid(String openid) {
        if (!StringUtils.hasText(openid)) {
            return null;
        }
        return baseMapper.findByOpenid(openid);
    }
    
    /**
     * 根据unionid查询用户
     * @param unionid 微信unionid
     * @return 用户信息
     */
    public User getUserByUnionid(String unionid) {
        if (!StringUtils.hasText(unionid)) {
            return null;
        }
        return baseMapper.findByUnionid(unionid);
    }
    
    /**
     * 根据手机号查询用户
     * @param phone 手机号
     * @return 用户信息
     */
    public User getUserByPhone(String phone) {
        if (!StringUtils.hasText(phone)) {
            return null;
        }
        return baseMapper.findByPhone(phone);
    }
    
    /**
     * 创建新用户
     * @param openid 微信openid
     * @param unionid 微信unionid
     * @param nickname 昵称
     * @param avatarUrl 头像URL
     * @param phone 手机号
     * @return 创建的用户
     */
    public User createUser(String openid, String unionid, String nickname, String avatarUrl, String phone) {
        User user = new User();
        user.setOpenid(openid);
        user.setUnionid(unionid);
        user.setNickname(StringUtils.hasText(nickname) ? nickname : "用户" + System.currentTimeMillis());
        user.setAvatarUrl(avatarUrl);
        user.setPhone(phone);
        user.setIsActive(true);
        user.setIsDeleted(false);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        boolean saved = this.save(user);
        if (saved) {
            return user;
        } else {
            log.error("Failed to create user with openid: {}, unionid: {}", openid, unionid);
            return null;
        }
    }
    
    /**
     * 更新用户信息
     * @param user 用户信息
     * @return 是否更新成功
     */
    public boolean updateUser(User user) {
        if (user == null || user.getId() == null) {
            return false;
        }
        user.setUpdateTime(LocalDateTime.now());
        return this.updateById(user);
    }
    
    /**
     * 更新用户信息
     * @param userId 用户ID
     * @param nickname 昵称
     * @param avatarUrl 头像URL
     * @param phone 手机号
     * @return 更新后的用户信息
     */
    public User updateUser(Long userId, String nickname, String avatarUrl, String phone) {
        if (userId == null) {
            return null;
        }
        
        User user = this.getById(userId);
        if (user == null) {
            return null;
        }
        
        boolean needUpdate = false;
        if (StringUtils.hasText(nickname) && !nickname.equals(user.getNickname())) {
            user.setNickname(nickname);
            needUpdate = true;
        }
        if (StringUtils.hasText(avatarUrl) && !avatarUrl.equals(user.getAvatarUrl())) {
            user.setAvatarUrl(avatarUrl);
            needUpdate = true;
        }
        if (StringUtils.hasText(phone) && !phone.equals(user.getPhone())) {
            user.setPhone(phone);
            needUpdate = true;
        }
        
        if (needUpdate) {
            user.setUpdateTime(LocalDateTime.now());
            boolean updated = this.updateById(user);
            if (updated) {
                return user;
            }
        }
        
        return user;
    }
    
    /**
     * 获取活跃用户列表
     * @param page 分页参数
     * @return 活跃用户分页列表
     */
    @Transactional(readOnly = true)
    public IPage<User> getActiveUsers(Page<User> page) {
        return baseMapper.findActiveUsers(page);
    }
    
    /**
     * 获取活跃用户列表
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 活跃用户分页列表
     */
    @Transactional(readOnly = true)
    public Page<User> getActiveUsers(int pageNum, int pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        return (Page<User>) baseMapper.findActiveUsers(page);
    }
    
    /**
     * 统计用户数量
     * @param isActive 是否活跃（null表示所有用户）
     * @param isDeleted 是否删除（null表示所有用户）
     * @return 用户数量
     */
    @Transactional(readOnly = true)
    public Long countUsers(Boolean isActive, Boolean isDeleted) {
        return baseMapper.countUsers(isActive, isDeleted);
    }
    
    /**
     * 更新用户活跃状态
     * @param userId 用户ID
     * @param isActive 是否活跃
     * @return 是否更新成功
     */
    public boolean updateUserActiveStatus(Long userId, Boolean isActive) {
        if (userId == null) {
            return false;
        }
        int result = baseMapper.updateActiveStatus(userId, isActive);
        if (result > 0) {
            return true;
        }
        return false;
    }
    
    /**
     * 批量更新用户活跃状态
     * @param userIds 用户ID列表
     * @param isActive 是否活跃
     * @return 更新的用户数量
     */
    public int batchUpdateActiveStatus(List<Long> userIds, Boolean isActive) {
        if (userIds == null || userIds.isEmpty()) {
            return 0;
        }
        int result = baseMapper.batchUpdateActiveStatus(userIds, isActive);
        return result;
    }
    
    /**
     * 根据昵称模糊查询用户
     * @param nickname 昵称关键字
     * @param page 分页参数
     * @return 用户分页列表
     */
    @Transactional(readOnly = true)
    public IPage<User> searchUsersByNickname(String nickname, Page<User> page) {
        if (!StringUtils.hasText(nickname)) {
            return new Page<>();
        }
        return baseMapper.findByNicknameLike(nickname, page);
    }
    
    /**
     * 根据昵称模糊查询用户
     * @param nickname 昵称关键字
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 用户分页列表
     */
    @Transactional(readOnly = true)
    public Page<User> searchUsersByNickname(String nickname, int pageNum, int pageSize) {
        if (!StringUtils.hasText(nickname)) {
            return new Page<>();
        }
        Page<User> page = new Page<>(pageNum, pageSize);
        return (Page<User>) baseMapper.findByNicknameLike(nickname, page);
    }
    
    /**
     * 软删除用户
     * @param userId 用户ID
     * @return 是否删除成功
     */
    public boolean softDeleteUser(Long userId) {
        if (userId == null) {
            return false;
        }
        User user = this.getById(userId);
        if (user == null) {
            return false;
        }
        user.setIsDeleted(true);
        user.setIsActive(false);
        user.setUpdateTime(LocalDateTime.now());
        boolean result = this.updateById(user);
        if (result) {
        }
        return result;
    }
    
    /**
     * 恢复已删除的用户
     * @param userId 用户ID
     * @return 是否恢复成功
     */
    public boolean restoreUser(Long userId) {
        if (userId == null) {
            return false;
        }
        User user = this.getById(userId);
        if (user == null) {
            return false;
        }
        user.setIsDeleted(false);
        user.setIsActive(true);
        user.setUpdateTime(LocalDateTime.now());
        boolean result = this.updateById(user);
        if (result) {
        }
        return result;
    }
    
    /**
     * 检查用户是否存在（根据openid或unionid）
     * @param openid 微信openid
     * @param unionid 微信unionid
     * @return 是否存在
     */
    @Transactional(readOnly = true)
    public boolean userExists(String openid, String unionid) {
        if (StringUtils.hasText(openid)) {
            User user = getUserByOpenid(openid);
            if (user != null) {
                return true;
            }
        }
        if (StringUtils.hasText(unionid)) {
            User user = getUserByUnionid(unionid);
            if (user != null) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 获取或创建用户
     * @param openid 微信openid
     * @param unionid 微信unionid
     * @param nickname 昵称
     * @param avatarUrl 头像URL
     * @param phone 手机号
     * @return 用户信息
     */
    public User getOrCreateUser(String openid, String unionid, String nickname, String avatarUrl, String phone) {
        User user = null;
        if (StringUtils.hasText(unionid)) {
            user = getUserByUnionid(unionid);
        }
        if (user == null && StringUtils.hasText(openid)) {
            user = getUserByOpenid(openid);
        }
        if (user == null) {
            user = createUser(openid, unionid, nickname, avatarUrl, phone);
        } else {
            boolean needUpdate = false;
            if (StringUtils.hasText(nickname) && !nickname.equals(user.getNickname())) {
                user.setNickname(nickname);
                needUpdate = true;
            }
            if (StringUtils.hasText(avatarUrl) && !avatarUrl.equals(user.getAvatarUrl())) {
                user.setAvatarUrl(avatarUrl);
                needUpdate = true;
            }
            if (StringUtils.hasText(phone) && !phone.equals(user.getPhone())) {
                user.setPhone(phone);
                needUpdate = true;
            }
            if (StringUtils.hasText(openid) && !openid.equals(user.getOpenid())) {
                user.setOpenid(openid);
                needUpdate = true;
            }
            if (StringUtils.hasText(unionid) && !unionid.equals(user.getUnionid())) {
                user.setUnionid(unionid);
                needUpdate = true;
            }
            
            if (needUpdate) {
                updateUser(user);
            }
        }
        
        return user;
    }
    
    /**
     * 查找不活跃用户
     * @param lastActiveTime 最后活跃时间
     * @return 不活跃用户列表
     */
    @Transactional(readOnly = true)
    public List<User> findInactiveUsers(LocalDateTime lastActiveTime) {
        if (lastActiveTime == null) {
            return List.of();
        }
        return baseMapper.findInactiveUsers(lastActiveTime);
    }
    
    /**
     * 查找有openid的活跃用户（用于推送）
     * @return 活跃用户列表
     */
    @Transactional(readOnly = true)
    public List<User> findActiveUsersWithOpenid() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_active", true)
                   .eq("is_deleted", false)
                   .isNotNull("openid")
                   .ne("openid", "")
                   .orderByDesc("create_time");
        return this.list(queryWrapper);
    }
    
    /**
     * 统计指定时间范围内的新用户数量
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 新用户数量
     */
    @Transactional(readOnly = true)
    public Long countNewUsers(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime == null || endTime == null) {
            return 0L;
        }
        return baseMapper.countUsersByCreateTime(startTime, endTime);
    }
    
    /**
     * 统计活跃用户数量
     * @return 活跃用户数量
     */
    @Transactional(readOnly = true)
    public Long countActiveUsers() {
        return baseMapper.countUsers(true, false);
    }
    
    /**
     * 统计指定时间范围内的活跃用户数量
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 活跃用户数量
     */
    @Transactional(readOnly = true)
    public Long countActiveUsers(LocalDateTime startTime, LocalDateTime endTime) {
        return baseMapper.countActiveUsersByTimeRange(startTime, endTime);
    }
    
    /**
     * 获取用户统计信息
     * @param userId 用户ID
     * @return 用户统计信息
     */
    @Transactional(readOnly = true)
    public Map<String, Object> getUserStats(Long userId) {
        Map<String, Object> stats = new HashMap<>();
        
        try {
            User user = this.getById(userId);
            if (user == null) {
                stats.put("error", "用户不存在");
                return stats;
            }
            
            stats.put("userId", userId);
            stats.put("nickname", user.getNickname());
            stats.put("createTime", user.getCreateTime());
            stats.put("isActive", user.getIsActive());
            
            // 计算注册天数
            if (user.getCreateTime() != null) {
                long daysSinceRegistration = ChronoUnit.DAYS.between(
                    user.getCreateTime().toLocalDate(), 
                    LocalDate.now()
                );
                stats.put("daysSinceRegistration", daysSinceRegistration);
            }
            
        } catch (Exception e) {
            log.error("获取用户统计信息失败: userId={}", userId, e);
            stats.put("error", e.getMessage());
        }
        
        return stats;
    }
}

